#include "CProcTextureThreshold.h"
using std::pair;
#include "CPerlinNoise.h"
#include <math.h>

CProcTextureThreshold::CProcTextureThreshold(float persistance, int octave, float intensity):
m_persistance(persistance), m_octave(octave), m_intensity(intensity){}

	
void CProcTextureThreshold::addThreshold(float threshold, const CColor& c)
{
	//if the threshold exists already, quit
	if(m_thresholds.find(threshold) != m_thresholds.end())
		return;

	//if the map is empty
	if(m_thresholds.empty())
	{
		m_thresholds.insert( pair<float, CColor> (threshold, c));
		return;
	}

	//insert the threshold at the right place
	map<float, CColor>::iterator i = m_thresholds.begin();
	map<float, CColor>::iterator next = i;

	while(i != m_thresholds.end())
	{
		if(threshold < i->first)
		{
			next = i;
			i = m_thresholds.end();
		}
		else
			i++;
	}

	m_thresholds.insert(next, pair<float, CColor>(threshold, c));

	
}

CColor CProcTextureThreshold::getColor(const CVector3f& p)const
{

	CVector3f newP = m_transform * p;

	//get perlin value
	float perlin = m_intensity * CPerlinNoise::perlin(newP, m_persistance, m_octave);
	perlin = fabs(perlin);

	//return CColor(1, 0, 0) * perlin;
	//find upper threshold
	map<float, CColor>::const_iterator next = m_thresholds.begin();
	bool found = false;
	while(next != m_thresholds.end() && !found)
	{
		if(perlin < next->first)
			found = true;
		else
			next++;
	}

	//check first and last
	if(next == m_thresholds.begin())
		return next->second;

	if(next == m_thresholds.end())
	{
		map<float, CColor>::const_iterator temp = next;
		temp--;
		if(perlin >= temp->first)
			return temp->second;
	}

	//interpolation
	map<float, CColor>::const_iterator previous = next;
	previous--;

	float f = (perlin - next->first) / (previous->first - next->first);

	return previous->second * (1 - f) + next->second * f;
	
}